package com.icez.like_star_library

import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.PointF
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.RelativeLayout
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator
import kotlin.random.Random


/**
 * 点赞效果控件
 * @sample
 * @author Icez
 */
class LikeStarLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {

    private var mDuration:Int = 3000

    private var mItemWidth:Int = 0

    private var mItemHeight:Int = 0

    init {
        val typedArray = context.obtainStyledAttributes(attrs,R.styleable.LikeStarLayout)
        mDuration = typedArray.getInteger(R.styleable.LikeStarLayout_duration,3000)
        mItemWidth = typedArray.getDimensionPixelOffset(R.styleable.LikeStarLayout_itemWidth,0)
        mItemHeight = typedArray.getDimensionPixelOffset(R.styleable.LikeStarLayout_itemHeight,0)
        typedArray.recycle()
    }

    private fun getScaleXAnimator(target: View?): ObjectAnimator? {
        return AnimatorUtil.instance.objectAnimator(
            target,
            AnimatorUtil.ObjectAnimatorType.SCALEX, null,
            {
                it.duration = mDuration/10L
            },
            null,
            0.2f,
            1f
        )
    }

    private fun getScaleYAnimator(target: View?): ObjectAnimator? {
        return AnimatorUtil.instance.objectAnimator(
            target,
            AnimatorUtil.ObjectAnimatorType.SCALEY, null,
            {
                it.duration = mDuration/10L
            },
            null,
            0.2f,
            1f
        )
    }

    private fun getAlphaAnimator(target: View?): ObjectAnimator? {
        return AnimatorUtil.instance.objectAnimator(
            target,
            AnimatorUtil.ObjectAnimatorType.ALPHA, null,
            {
                it.duration = mDuration/10L
            },
            null,
            0.2f,
            1f
        )
    }

    /**
     * 获取贝塞尔曲线动画
     *
     * @param target 控件
     * @return
     */
    private fun getBezierAnimator(target: View?): ValueAnimator? {
        val bezierEvaluator = BezierEvaluator(getMiddlePointF(1), getMiddlePointF(2))
        return AnimatorUtil.instance.valueAnimator(
            target,
            AnimatorUtil.ValueAnimatorType.OBJECT,
            bezierEvaluator,
            {
                it?.duration = mDuration.toLong()
            },
            {
                val pointF = it.animatedValue as PointF
                target?.x = pointF.x
                target?.y = pointF.y
                target?.alpha = 1 - it.animatedFraction
            }, PointF(width / 2f - mItemWidth/2f, height - mItemHeight/2f),PointF
        ((0..width).random().toFloat(),0f))
    }

    /**
     * 获取中间点
     *
     * @param index 索引
     * @return
     */
    private fun getMiddlePointF(index: Int): PointF {
        val pointF = PointF()
        val middleWidth = (0..width).random()

        if (index == 1) {
            val middleHeight = height / 2f
            pointF.y = middleHeight
        } else if (index == 2) {
            val middleHeight = height / 2f + height / 4f
            pointF.y = middleHeight
        } else {
            throw Exception("index 只能是1或者2")
        }
        pointF.x = middleWidth.toFloat()
        return pointF
    }

    /**
     * 添加item
     *
     */
    public fun <VB:ViewDataBinding> addItem(viewResId:Int,onLayoutListener:((binding:VB)->Unit)?) {
        val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
        lp.addRule(CENTER_HORIZONTAL, TRUE)
        lp.addRule(ALIGN_PARENT_BOTTOM, TRUE)
        val binding = DataBindingUtil.inflate<VB>(LayoutInflater.from(context),viewResId,null,false)
        val itemView = binding.root
        itemView?.layoutParams = lp
        addView(itemView)
        if (onLayoutListener != null) {
            onLayoutListener(binding)
        }
        val alphaAnima = getAlphaAnimator(itemView)
        val scaleXAnima = getScaleXAnimator(itemView)
        val scaleYAnima = getScaleYAnimator(itemView)
        val bezierAnima = getBezierAnimator(itemView)
        AnimatorUtil.instance.animatorSet(itemView, {
            it.interpolator = LinearOutSlowInInterpolator()
        }, {
            removeView(itemView)
        }, alphaAnima,scaleXAnima,scaleYAnima,bezierAnima)
    }
}